package com.ruoyi.web.controller.tool;

import com.jcraft.jsch.*;

import java.io.File;

class SFTPUploadFolder
{
    public static void main(String[] args)
    {
        String sftpHost = "123.249.98.163";
        int sftpPort = 22; // 默认SFTP端口是22
        String sftpUser = "jyjt";
        String sftpPassword = "9T&bH5!mQe1#";
        String localDir = "C:\\basedata"; // 本地文件夹路径
        String remoteDir = "/data/nasfile/jyjt"; // 远程文件夹路径

        Session session = null;
        Channel channel = null;
        ChannelSftp channelSftp = null;

        try
        {
            // 设置JSch对象并连接服务器
            JSch jsch = new JSch();
            session = jsch.getSession(sftpUser, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            // 打开SFTP通道
            channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;

            System.out.println("开始上传文件夹: " + localDir + " -> " + remoteDir);

            // 上传整个目录
            uploadDirectory(new File(localDir), remoteDir, channelSftp);

            System.out.println("文件夹上传完成!");

        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            // 关闭通道和会话连接
            if (channelSftp != null)
            {
                channelSftp.exit();
            }
            if (channel != null)
            {
                channel.disconnect();
            }
            if (session != null)
            {
                session.disconnect();
            }
        }
    }

    private static void uploadDirectory(File localDirectory, String remoteParentDir, ChannelSftp channelSftp) throws SftpException
    {
        try {
            // 检查远程目录是否存在，如果不存在则创建
            try {
                channelSftp.cd(remoteParentDir);
                System.out.println("进入目录: " + remoteParentDir);
            } catch (SftpException e) {
                // 如果目录不存在，则创建
                if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
                    createRemoteDirectory(remoteParentDir, channelSftp);
                    channelSftp.cd(remoteParentDir);
                    System.out.println("创建并进入目录: " + remoteParentDir);
                } else {
                    throw e;
                }
            }

            // 遍历本地目录并上传文件
            File[] files = localDirectory.listFiles();
            if (files != null)
            {
                for (File file : files)
                {
                    if (file.isFile())
                    {
                        // 上传文件
                        String remoteFilePath = remoteParentDir + "/" + file.getName();
                        channelSftp.put(file.getAbsolutePath(), remoteFilePath);
                        System.out.println("  上传文件: " + file.getName() + " -> " + remoteFilePath);
                    } else if (file.isDirectory())
                    {
                        // 递归上传子目录
                        String subRemoteDir = remoteParentDir + "/" + file.getName();
                        System.out.println("处理子目录: " + file.getName() + " -> " + subRemoteDir);
                        uploadDirectory(file, subRemoteDir, channelSftp);
                    }
                }
            } else
            {
                System.out.println("目录为空: " + localDirectory.getAbsolutePath());
            }
        } catch (Exception e) {
            System.err.println("上传目录出错: " + localDirectory.getAbsolutePath());
            e.printStackTrace();
        }
    }

    /**
     * 递归创建远程目录
     */
    private static void createRemoteDirectory(String remoteDir, ChannelSftp channelSftp) throws SftpException {
        String[] folders = remoteDir.split("/");
        String path = "";
        for (String folder : folders) {
            if(folder.isEmpty())
            {
                continue;
            }
            path += "/" + folder;
            try {
                channelSftp.mkdir(path);
                System.out.println("创建远程目录: " + path);
            } catch (SftpException e) {
                if (e.id != ChannelSftp.SSH_FX_FAILURE) {
                    throw e;
                }
                // 目录已存在，继续
                System.out.println("目录已存在: " + path);
            }
        }
    }
}